home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / fs / fsCommand.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-19  |  12.8 KB  |  521 lines

  1. /* 
  2.  * fsCommand.c --
  3.  *
  4.  *    The guts of the Fs_Command system call.  This is used to
  5.  *    set/get various filesystem parameters.
  6.  *
  7.  *
  8.  * Copyright 1985 Regents of the University of California
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software and its documentation for any purpose and without
  11.  * fee is hereby granted, provided that the above copyright
  12.  * notice appear in all copies.  The University of California
  13.  * makes no representations about the suitability of this
  14.  * software for any purpose.  It is provided "as is" without
  15.  * express or implied warranty.
  16.  */
  17.  
  18. #ifndef lint
  19. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/fs/fsCommand.c,v 9.8 92/06/01 14:44:05 kupfer Exp $ SPRITE (Berkeley)";
  20. #endif not lint
  21.  
  22.  
  23. #include <sprite.h>
  24. #include <bstring.h>
  25. #include <fs.h>
  26. #include <fsutil.h>
  27. #include <fsNameOps.h>
  28. #include <fsprefix.h>
  29. #include <fslcl.h>
  30. #include <fscache.h>
  31. #include <fspdev.h>
  32. #include <fsStat.h>
  33. #include <fsdm.h>
  34. #include <timer.h>
  35. #include <user/fsCmd.h>
  36. #include <rpc.h>
  37. #include <sched.h>
  38. #include <fsrmt.h>
  39. #include <vm.h>
  40. #include <stdlib.h>
  41. #include <stdio.h>
  42. #include <lfs.h>
  43.  
  44. #define SWAP_TO_BUFFER(int1, buffer) \
  45.     if ((int *)buffer != (int *)NIL && (int *)buffer != (int *)0) {    \
  46.     register int tmp;                        \
  47.     tmp = int1 ; int1 = *(int *)buffer ; *(int *)buffer = tmp;    \
  48.     }
  49.  
  50. /* Forward references: */
  51.  
  52. static void ZeroFsStats _ARGS_((void));
  53.  
  54.  
  55. /*
  56.  *----------------------------------------------------------------------
  57.  *
  58.  * Fs_Command --
  59.  *
  60.  *    Hook into the fs module.  System parameters can be adjusted,
  61.  *    the prefix table modified, and filesystem stats can be returned.
  62.  *
  63.  * Results:
  64.  *    0 or an error code from any of the operations.
  65.  *
  66.  * Side effects:
  67.  *    See description by each command.
  68.  *
  69.  *----------------------------------------------------------------------
  70.  */
  71. ReturnStatus
  72. Fs_Command(command, bufSize, buffer)
  73.     int command;
  74.     int bufSize;
  75.     Address buffer;
  76. {
  77.     ReturnStatus     status = SUCCESS;
  78.     extern    int    fscache_MaxBlockCleaners;
  79.     extern    int    fscache_NumReadAheadBlocks;
  80.     extern    Boolean    fsconsist_ClientCachingEnabled;
  81.  
  82.     switch(command) {
  83.     case FS_PREFIX_LOAD: {
  84.         /*
  85.          * Load the prefix and serverID into the prefix table.
  86.          * serverID is usually FS_NO_SERVER, although a known serverID
  87.          * can be loaded into the table.
  88.          */
  89.         Fs_PrefixLoadInfo *argPtr = (Fs_PrefixLoadInfo *) buffer;
  90.         if (argPtr->prefix[0] != '/' ||(argPtr->serverID < 0 || 
  91.         argPtr->serverID >= NET_NUM_SPRITE_HOSTS)) {
  92.         status = FS_INVALID_ARG;
  93.         } else {
  94.         int prefixFlags = FSPREFIX_IMPORTED;
  95.  
  96.         if (argPtr->serverID != RPC_BROADCAST_SERVER_ID) {
  97.             prefixFlags |= FSPREFIX_REMOTE | FSPREFIX_FORCED;
  98.         }
  99.         Fsprefix_Load(argPtr->prefix, argPtr->serverID, prefixFlags);
  100.         status = SUCCESS;
  101.         }
  102.         break;
  103.     }
  104.     case FS_PREFIX_EXPORT: {
  105.         /*
  106.          * Export a local directory under a prefix.
  107.          */
  108.         Fs_TwoPaths *argPtr = (Fs_TwoPaths *)buffer;
  109.         char *localPath, *prefix;
  110.         Fs_Stream *streamPtr;
  111.  
  112.         localPath = (char *)malloc(argPtr->pathLen1);
  113.         prefix = (char *)malloc(argPtr->pathLen2);
  114.         status = Vm_CopyIn(argPtr->pathLen1, argPtr->path1, localPath);
  115.         if (status == SUCCESS) {
  116.         status = Vm_CopyIn(argPtr->pathLen2, argPtr->path2, prefix);
  117.         if (status == SUCCESS) {
  118.             status = Fs_Open(localPath, FS_READ|FS_FOLLOW,
  119.                         FS_DIRECTORY, 0, &streamPtr);
  120.             if (status == SUCCESS) {
  121.             if (streamPtr->ioHandlePtr->fileID.type !=
  122.                 FSIO_LCL_FILE_STREAM) {
  123.                 printf(
  124.             "Tried to export non-local file \"%s\" as prefix \"%s\"\n",
  125.                 localPath, prefix);
  126.                 (void)Fs_Close(streamPtr);
  127.                 status = FS_NO_ACCESS;
  128.             } else {
  129.                 (void)Fsprefix_Install(prefix,streamPtr->ioHandlePtr,
  130.                             FS_LOCAL_DOMAIN,
  131.             FSPREFIX_EXPORTED|FSPREFIX_IMPORTED|FSPREFIX_OVERRIDE);
  132.             }
  133.             }
  134.         }
  135.         }
  136.         free(prefix);
  137.         free(localPath);
  138.         break;
  139.     }
  140.     case FS_PREFIX_CLEAR: {
  141.         /*
  142.          * Clear the handle information about a prefix.
  143.          */
  144.         status = Fsprefix_Clear(buffer, FALSE, TRUE);
  145.         break;
  146.     }
  147.     case FS_PREFIX_DELETE: {
  148.         /*
  149.          * Remote a prefix table entry all-together.
  150.          */
  151.         status = Fsprefix_Clear(buffer, TRUE, TRUE);
  152.         break;
  153.     }
  154.     case FS_PREFIX_CONTROL: {
  155.         /*
  156.          * Modify the export list associated with a prefix.
  157.          */
  158.         register Fs_PrefixControl *controlPtr;
  159.         controlPtr = (Fs_PrefixControl *)buffer;
  160.         if (bufSize < sizeof(Fs_PrefixControl)) {
  161.         status = GEN_INVALID_ARG;
  162.         } else {
  163.         Fsprefix_Export(controlPtr->prefix, controlPtr->clientID,
  164.                 controlPtr->delete);
  165.         status = SUCCESS;
  166.         }
  167.         break;
  168.     }
  169.     case FS_RAISE_MIN_CACHE_SIZE: {
  170.         /*
  171.          * Make the minimum size of the file system block cache larger.
  172.          */
  173.         if (buffer != (Address)NIL && buffer != (Address)0) {
  174.         Fscache_SetMinSize(*(int *) buffer);
  175.         }
  176.         break;
  177.     }
  178.     case FS_LOWER_MAX_CACHE_SIZE: {
  179.         /*
  180.          * Make the minimum size of the file system block cache larger.
  181.          */
  182.         if (buffer != (Address)NIL && buffer != (Address)0) {
  183.         Fscache_SetMaxSize(*(int *) buffer);
  184.         }
  185.         break;
  186.     }
  187.     case FS_DISABLE_FLUSH: {
  188.         /*
  189.          * Turn on or off automatic flushing of the cache.
  190.          */
  191.         SWAP_TO_BUFFER(fsutil_ShouldSyncDisks, buffer);
  192.         break;
  193.     }
  194.     /*
  195.      * The following cases are used to set flags and to
  196.      * return their old values.
  197.      */
  198.     case FS_SET_CACHE_DEBUG: {
  199.         /*
  200.          * Set the cache debug flag.
  201.          */
  202.         extern int fsconsist_Debug;
  203.         SWAP_TO_BUFFER(fsconsist_Debug, buffer);
  204.         break;
  205.     }
  206.     case FS_SET_MIG_DEBUG: {
  207.         /*
  208.          * Set the migration debug flag.
  209.          */
  210.         extern int fsio_MigDebug;
  211.         SWAP_TO_BUFFER(fsio_MigDebug, buffer);
  212.         break;
  213.     }
  214.     case FS_SET_RPC_DEBUG: {
  215.         /*
  216.          * Set the rpc debug flag.
  217.          */
  218.         SWAP_TO_BUFFER(fsrmt_RpcDebug, buffer);
  219.         break;
  220.     }
  221.     case FS_SET_RPC_TRACING: {
  222.         /*
  223.          * Set the rpc tracing flag.
  224.          */
  225.         SWAP_TO_BUFFER(rpc_Tracing, buffer);
  226.         break;
  227.     }
  228.     case FS_SET_RPC_NO_TIMEOUTS: {
  229.         /*
  230.          * Set the rpc "no timeouts" flag, useful when debugging.
  231.          */
  232.         SWAP_TO_BUFFER(rpc_NoTimeouts, buffer);
  233.         break;
  234.     }
  235.     case FS_SET_NAME_CACHING: {
  236.         /*
  237.          * Set the rpc tracing flag.
  238.          */
  239.         extern int fslclNameCaching;
  240.         SWAP_TO_BUFFER(fslclNameCaching, buffer);
  241.         break;
  242.     }
  243.     case FS_SET_CLIENT_CACHING: {
  244.         /*
  245.          * Set the rpc tracing flag.
  246.          */
  247.         SWAP_TO_BUFFER(fsconsist_ClientCachingEnabled, buffer);
  248.         break;
  249.     }
  250.     case FS_SET_RPC_CLIENT_HIST: {
  251.         extern int rpcCallTiming;
  252.         SWAP_TO_BUFFER(rpcCallTiming, buffer);
  253.         break;
  254.     }
  255.     case FS_SET_RPC_SERVER_HIST: {
  256.         extern int rpcServiceTiming;
  257.         SWAP_TO_BUFFER(rpcServiceTiming, buffer);
  258.         break;
  259.     }
  260.     case FS_SET_NO_STICKY_SEGS: {
  261.         extern Boolean vm_NoStickySegments;
  262.         SWAP_TO_BUFFER(vm_NoStickySegments, buffer);
  263.         break;
  264.     }
  265.     case FS_TEST_CS: {
  266.         register    int    i;
  267.         Timer_Ticks    startTicks, endTicks, diffTicks;
  268.         Time    time;
  269.         int        us;
  270.  
  271.         Timer_GetCurrentTicks(&startTicks);
  272.         for (i = *(int *) buffer; i > 0; i--) {
  273.         Sched_ContextSwitch(PROC_READY);
  274.         }
  275.         Timer_GetCurrentTicks(&endTicks);
  276.         Timer_SubtractTicks(endTicks, startTicks, &diffTicks);
  277.         Timer_TicksToTime(diffTicks, &time);
  278.         us = (time.seconds * 1000000) + time.microseconds;
  279.         printf("microseconds = %d per CS = %d\n", us,
  280.                us / *(int *)buffer);
  281.         break;
  282.     }
  283.     case FS_EMPTY_CACHE: {
  284.         int *numLockedBlocksPtr = (int *)buffer;
  285.  
  286.         Fscache_Empty(numLockedBlocksPtr);
  287.         break;
  288.     }
  289.     case FS_ZERO_STATS: {
  290.         ZeroFsStats();
  291.         status = SUCCESS;
  292.         break;
  293.     }
  294.     case FS_RETURN_STATS: {
  295.         if (bufSize > 0) {
  296.         if (bufSize > sizeof(Fs_Stats)) {
  297.             bufSize = sizeof(Fs_Stats);
  298.         }
  299.         bcopy((Address) &fs_Stats, buffer, bufSize);
  300.         status = SUCCESS;
  301.         } else {
  302.         status = FS_INVALID_ARG;
  303.         }
  304.         break;
  305.     }
  306.     case FS_RETURN_LIFE_TIMES: {
  307.         if (bufSize >= sizeof(Fs_TypeStats)) {
  308.         bcopy((Address)&fs_TypeStats, buffer, sizeof(Fs_TypeStats));
  309.         status = SUCCESS;
  310.         } else {
  311.         status = FS_INVALID_ARG;
  312.         }
  313.         break;
  314.     }
  315.     case FS_GET_FRAG_INFO: {
  316.         int    *arrPtr = (int *)buffer;
  317.  
  318.         Fscache_CheckFragmentation(arrPtr, arrPtr + 1, arrPtr + 2);
  319.         break;
  320.     }
  321.     case FS_SET_CLEANER_PROCS:
  322.         SWAP_TO_BUFFER(fscache_MaxBlockCleaners, buffer);
  323.         break;
  324.     case FS_SET_READ_AHEAD:
  325.         SWAP_TO_BUFFER(fscache_NumReadAheadBlocks, buffer);
  326.         break;
  327.     case FS_REREAD_SUMMARY_INFO:
  328.         status = Fsdm_RereadSummaryInfo(buffer);
  329.         break;
  330.     case FS_SET_BLOCK_SKEW: {
  331.         /*
  332.          * Set the block allocation gap.
  333.          */
  334.         extern int ofs_AllocGap;
  335.         SWAP_TO_BUFFER(ofs_AllocGap, buffer);
  336.         break;
  337.     }
  338.     case FS_DO_L1_COMMAND:
  339.         Dev_InvokeConsoleCmd(*(int *)buffer);
  340.         break;
  341.     default:
  342.         if ((command >= FS_FIRST_LFS_COMMAND) &&
  343.             (command <= FS_LAST_LFS_COMMAND)) {
  344.         status = Lfs_Command(command, bufSize, buffer);
  345.         } else {
  346.         status = FS_INVALID_ARG;
  347.         }
  348.     }
  349.     return(status);
  350. }
  351.  
  352. #ifdef notdef
  353. /*
  354.  *----------------------------------------------------------------------
  355.  *
  356.  * Fs_Cat --
  357.  *
  358.  *    Cat a file to the screen.  The named file is opened, then
  359.  *    a series of reads are done and the returned data is printed
  360.  *    on the screen.  (Used when testing simple kernels.)
  361.  *
  362.  * Results:
  363.  *    0 or an error code from any of the file operations.
  364.  *
  365.  * Side effects:
  366.  *    Does an open, reads and write, and a close.
  367.  *
  368.  *----------------------------------------------------------------------
  369.  */
  370. int
  371. Fs_Cat(fileName)
  372.     char *fileName;
  373. {
  374.     int error;
  375.     Fs_Stream *streamPtr;
  376.     int offset;
  377.     Address buffer;
  378.  
  379.     streamPtr = (Fs_Stream *)NIL;
  380.     error = Fs_Open(fileName, FS_READ|FS_FOLLOW, FS_FILE, 0, &streamPtr);
  381.     if (error) {
  382.     return(error);
  383.     }
  384.  
  385. #define CAT_BUFSIZE    80
  386.  
  387.     buffer = malloc(CAT_BUFSIZE);
  388.     offset = 0;
  389.     while (1) {
  390.     int savedLen, len;
  391.  
  392.     bzero(buffer, CAT_BUFSIZE);
  393.  
  394.     savedLen = len = CAT_BUFSIZE;
  395.     error = Fs_Read(streamPtr, buffer, offset, &len);
  396.     if (error || len < savedLen) {
  397.         break;
  398.     } else {
  399.         offset += len;
  400.     }
  401.     printf("%s", buffer);
  402.     }
  403.     (void)Fs_Close(streamPtr);
  404.     free(buffer);
  405.     return(error);
  406. }
  407. #endif /* notdef */
  408.  
  409. #ifdef notdef
  410. /*
  411.  *----------------------------------------------------------------------
  412.  *
  413.  * Fs_Copy --
  414.  *
  415.  *    Copy a file. (Used when testing simple kernels.)
  416.  *
  417.  * Results:
  418.  *    0 or an error code from any of the file operations.
  419.  *
  420.  * Side effects:
  421.  *    Creates a copy of the first file in the second.
  422.  *
  423.  *----------------------------------------------------------------------
  424.  */
  425. int
  426. Fs_Copy(srcFileName, dstFileName)
  427.     char *srcFileName;
  428.     char *dstFileName;
  429. {
  430.     int error;
  431.     Fs_Stream *srcStreamPtr;
  432.     Fs_Stream *dstStreamPtr;
  433.     int offset;
  434.     Address buffer;
  435.  
  436.     srcStreamPtr = (Fs_Stream *)NIL;
  437.     error = Fs_Open(srcFileName, FS_READ|FS_FOLLOW, FS_FILE, 0, &srcStreamPtr);
  438.     if (error) {
  439.     Sys_SafePrintf("Fs_Copy: can't open source file (%s)\n", srcFileName);
  440.     return(error);
  441.     }
  442.     dstStreamPtr = (Fs_Stream *)NIL;
  443.     error = Fs_Open(dstFileName, FS_CREATE|FS_WRITE|FS_FOLLOW, FS_FILE, 0666, &dstStreamPtr);
  444.     if (error) {
  445.     Sys_SafePrintf("Fs_Copy: can't open destination file (%s)\n",
  446.                  dstFileName);
  447.     (void)Fs_Close(srcStreamPtr);
  448.     return(error);
  449.     }
  450.  
  451. #define CP_BUFSIZE    2048
  452.  
  453.     buffer = malloc(CP_BUFSIZE);
  454.     offset = 0;
  455.     while (1) {
  456.     int len;
  457.  
  458.     len = CP_BUFSIZE;
  459.     error = Fs_Read(srcStreamPtr, buffer, offset, &len);
  460.     if (error) {
  461.         Sys_SafePrintf("Fs_Copy: read failed\n");
  462.         break;
  463.     } else if (len == 0) {
  464.         break ;
  465.     }
  466.     error = Fs_Write(dstStreamPtr, buffer, offset, &len);
  467.     if (error) {
  468.         Sys_SafePrintf("Fs_Copy: write failed\n");
  469.         break;
  470.     }
  471.     offset += len;
  472.     }
  473.     Sys_SafePrintf("Fs_Copy: copied %d bytes\n", offset);
  474.  
  475.     (void)Fs_Close(srcStreamPtr);
  476.     (void)Fs_Close(dstStreamPtr);
  477.     free(buffer);
  478.     return(error);
  479. }
  480. #endif /* notdef */
  481.  
  482.  
  483. /*
  484.  *----------------------------------------------------------------------
  485.  *
  486.  * ZeroFsStats --
  487.  *
  488.  *    Reset counters in the Fs_Stats structure, leaving state information 
  489.  *    alone.
  490.  *
  491.  * Results:
  492.  *    None.
  493.  *
  494.  * Side effects:
  495.  *    None.
  496.  *
  497.  *----------------------------------------------------------------------
  498.  */
  499.  
  500. static void
  501. ZeroFsStats()
  502. {
  503.     bzero(&fs_Stats.cltName, sizeof(fs_Stats.cltName));
  504.     bzero(&fs_Stats.srvName, sizeof(fs_Stats.srvName));
  505.     bzero(&fs_Stats.gen, sizeof(fs_Stats.gen));
  506.     Fscache_ZeroStats();
  507.     bzero(&fs_Stats.alloc, sizeof(fs_Stats.alloc));
  508.     Fsutil_ZeroHandleStats();
  509.     bzero(&fs_Stats.prefix, sizeof(fs_Stats.prefix));
  510.     bzero(&fs_Stats.lookup, sizeof(fs_Stats.lookup));
  511.     fs_Stats.nameCache.accesses = 0;
  512.     fs_Stats.nameCache.hits = 0;
  513.     fs_Stats.nameCache.replacements = 0;
  514.     fs_Stats.object.dirFlushed = 0;
  515.     bzero(&fs_Stats.recovery, sizeof(fs_Stats.recovery));
  516.     bzero(&fs_Stats.consist, sizeof(fs_Stats.consist));
  517.     bzero(&fs_Stats.writeBack, sizeof(fs_Stats.writeBack));
  518.     bzero(&fs_Stats.rmtIO, sizeof(fs_Stats.rmtIO));
  519.     bzero(&fs_Stats.mig, sizeof(fs_Stats.mig));
  520. }
  521.